package pack;

import java.awt.event.KeyEvent;
import java.util.ArrayList;
import net.useobjects.AbstractMovableRotatableGroup;
import net.useobjects.Circle;
import net.useobjects.geom.Position;

public abstract class ValidaciaPremiestnenia extends Hranica {

    private double distanceStrelecFromKamen, distanceZbranFromKamen,distanceKruhFromKamen;
    private int i=0; 

    public ValidaciaPremiestnenia(AbstractMovableRotatableGroup parent, Position pozicia, double angle) {//
        super(parent, pozicia, angle);//
    }

    public ValidaciaPremiestnenia(AbstractMovableRotatableGroup parent, Position pozicia) {//
        super(parent, pozicia);//
    }

    Position transformLocalCoordinates(Position poloha, Position poloha_0) {

        //poloha_0 : lokalna sustava do ktorej transformujeme
        Position newPoloha = new Position(0, 0);

        newPoloha.setX(poloha.getX() - poloha_0.getX());
        newPoloha.setY(poloha.getY() - poloha_0.getY());
        return newPoloha;
    }

    //ak true, tak sa moze premiestnit
    private boolean mozePremiestnit(Strelec strelec, Kamen kamen, int keyEvent) {

        distanceStrelecFromKamen = getPolarRadius(transformLocalCoordinates(strelec.getCircle().getPositionInRootGroup(), kamen.getPositionInRootGroup()));//poloha strelca v lokalnej sustave kamena
        distanceZbranFromKamen = getPolarRadius(transformLocalCoordinates(strelec.getPolygon().getPositionInRootGroup(), kamen.getPositionInRootGroup()));

        if (keyEvent == KeyEvent.VK_UP) {
            //20 je priemer kruhu "strelec"
            return distanceStrelecFromKamen > getPolomer(kamen) + 20 || distanceZbranFromKamen - 5 > getPolomer(kamen);
        } else { //if( keyEvent == KeyEvent.VK_DOWN) {
            //20 je priemer kruhu "strelec"
            return distanceStrelecFromKamen > getPolomer(kamen) + 10 || distanceZbranFromKamen - 10 < getPolomer(kamen);
        }

    }

    //invokuje Ciel
    //ak true, tak sa moze premiestnit
    private boolean mozePremiestnit(Circle kruh, Kamen kamen) {

        distanceKruhFromKamen = getPolarRadius(transformLocalCoordinates(kruh.getPositionInRootGroup(), kamen.getPositionInRootGroup()) );//poloha kruhu v lokalnej sustave kamena
        return distanceKruhFromKamen > (getPolomer(kamen) + 10);
    }

//    private boolean zasah(Ciel ciel, Strela strela) {
//        double distanceCielFromCiel = getPolarRadius(transformLocalCoordinates(strela.getPositionInRootGroup(),ciel.getPositionInRootGroup()));//poloha kruhu v lokalnej sustave kamena
//        return (distanceCielFromCiel < 10);//10 je polomer ciela
//    }

    protected boolean mozemSaPohnut(Strelec strelec, ArrayList<Kamen> zoznamKamenov, int KeyEvent) {

        for (Kamen kamen : zoznamKamenov) {

            if (mozePremiestnit(strelec, kamen, KeyEvent) == false) {

                return false;
            }
        }

        return true;
    }

    protected boolean mozemSaPohnut(Circle kruh, ArrayList<Kamen> zoznamKamenov) {
        
        for (Kamen kamen : zoznamKamenov) {

            if (mozePremiestnit(kruh, kamen) == false) {

                return false;
            }
        }

        return true;
    }

//    protected boolean trafilCiel(Ciel ciel, ArrayList<Strela> zoznamStriel) {
//
//        if (zoznamStriel.isEmpty()) {
//            return false;
//        }
//
//        for (Strela strela : zoznamStriel) {
//            if (zasah(ciel, strela) == false) {
//                return false;
//            }
//        }
//        return true;
//
//    }

    protected boolean jeVoSvete(Position poloha, double orientation, int keyEvent) {
        boolean a=sever(poloha, orientation, keyEvent) && juh(poloha, orientation, keyEvent) && vychod(poloha, orientation, keyEvent)
                && zapad(poloha, orientation, keyEvent);
        return a;

    }

    protected boolean jeVoSvete(Circle kruh) {
        double orientation = kruh.getRotation();

        return jeVoSvete(kruh.getPositionInRootGroup(), orientation, KeyEvent.VK_UP);
    }

    private boolean sever(Position poloha, double orientation, int keyEvent) {

        if (keyEvent == KeyEvent.VK_UP) {
            
            return poloha.getY() > 20 || Math.signum(Math.sin(orientation)) > 0; //signum sinusu, urcime kvadrant
        } 
        else { //if( keyEvent == KeyEvent.VK_DOWN) {
            return poloha.getY() > 20 || Math.signum(Math.sin(orientation)) < 0; //signum sinusu, urcime kvadrant
        }

    }

    private boolean juh(Position poloha, double orientation, int keyEvent) {

        if (keyEvent == KeyEvent.VK_UP) {
            return poloha.getY() < 580 || Math.signum(Math.sin(orientation)) < 0;
        } else { //if( keyEvent == KeyEvent.VK_DOWN) {
            return poloha.getY() < 580 || Math.signum(Math.sin(orientation)) > 0;
        }
    }

    private boolean vychod(Position poloha, double orientation, int keyEvent) {

        if (keyEvent == KeyEvent.VK_UP) {
            return poloha.getX() < 780 || Math.signum(Math.cos(orientation)) < 0;
        } else { //if( keyEvent == KeyEvent.VK_DOWN) {
            return poloha.getX() < 780 || Math.signum(Math.cos(orientation)) > 0;
        }
    }

    private boolean zapad(Position poloha, double orientation, int keyEvent) {

        if (keyEvent == KeyEvent.VK_UP) {
            return poloha.getX() > 20 || Math.signum(Math.cos(orientation)) > 0;
        } else { //if( keyEvent == KeyEvent.VK_DOWN) {
            return poloha.getX() > 20 || Math.signum(Math.cos(orientation)) < 0;
        }
    }

}
